﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SaleManagement.Web.App_Code;
using SaleManagement.Domains;
using SaleManagement.Services;
using System.Data;

namespace SaleManagement.Web.Pages
{
  public partial class GuaranteeDetail : BasePage
  {
    #region Properties

    private string _gvGuaranteeDetailError = string.Empty;

    private DataTable GuaranteeDetailTable
    {
      get
      {
        if (Session["GuaranteeDetailTable"] == null)
        {
          DataTable dt = new DataTable();
          Session["GuaranteeDetailTable"] = dt;
        }
        return Session["GuaranteeDetailTable"] as DataTable;
      }

      set
      {
        Session["GuaranteeDetailTable"] = value;
      }
    }

    private int DetailId
    {
      get
      {
        if (Session["GuaranteeDetailId"] == null)
        {
          Session["GuaranteeDetailId"] = 0;
        }

        return Convert.ToInt32(Session["GuaranteeDetailId"]);
      }

      set
      {
        Session["GuaranteeDetailId"] = value;
      }
    }

    #endregion

    #region Events

    protected void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack && !IsCallback)
      {
        if (!string.IsNullOrEmpty(Request.QueryString["id"]))
        {
          hfGuaranteeId.Value = Request.QueryString["id"];
          btnPrint.ClientVisible = true;
        }

        InitPage();
        LoadInfo();
      }
    }

    protected void gvGuaranteeDetail_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
    {
      string[] para = e.Parameters.Split('|');
      switch (para[0])
      {
        case "DeleteDetail":
          _gvGuaranteeDetailError = DeleteGuaranteeDetail(Convert.ToInt32(para[1]));
          break;
        case "SaveDetail":
          _gvGuaranteeDetailError = SaveDetail();
          break;
        case "Save":
          _gvGuaranteeDetailError = Save();
          break;
        case "Previous":
          _gvGuaranteeDetailError = SavePreviousPurchase();
          break;
        default:
          break;
      }

      LoadDetailList();
    }

    protected void gvGuaranteeDetail_CustomJSProperties(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewClientJSPropertiesEventArgs e)
    {
      e.Properties["cpInnerError"] = _gvGuaranteeDetailError;
    }

    protected void gvCustomer_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
    {
      LoadCustomerList();
    }

    protected void gvCustomer_PageIndexChanged(object sender, EventArgs e)
    {
      LoadCustomerList();
    }

    protected void cbxProduct_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
    {
      int groupId = Convert.ToInt32(cbxProductGroup.Value);
      ProductGroup group = new ProductGroupService().GetById(groupId);
      if (group != null)
      {
        cbxProduct.DataSource = new ProductService().GetByGroupId(groupId);
        cbxProduct.DataBind();
      }
    }

    #endregion

    #region Helpers

    private void InitPage()
    {
      deAttendReturn.Date = DateTime.Now.AddDays(7);
      deReceiveDate.Date = DateTime.Now;

      cbxRepository.DataSource = new RepositoryService().Search(StatusList.RepositoryType.GUARANTEE);
      cbxRepository.DataBind();
      if (cbxRepository.Items.Count > 0)
      {
        cbxRepository.SelectedIndex = 0;
      }

      cbxProductGroup.DataSource = new ProductGroupService().GetAll();
      cbxProductGroup.DataBind();

    }

    private void LoadInfo()
    {
      int guaranteeId = 0;
      if (int.TryParse(hfGuaranteeId.Value, out guaranteeId))
      {
        Domains.GuaranteeList guaranteeList = new GuaranteeListService().GetById(guaranteeId);
        if (guaranteeList != null)
        {
          #region Purchase
          deAttendReturn.Date = guaranteeList.AttendReturn.HasValue ? guaranteeList.AttendReturn.Value : DateTime.Now.AddDays(7);
          deReceiveDate.Date = guaranteeList.ReceivedDate;
          txtTotalMoney.Text = guaranteeList.TotalFee.HasValue ? guaranteeList.TotalFee.Value.ToString() : "0";
          #endregion

          #region Customer
          if (guaranteeList.CustomerId.HasValue)
          {
            hfCustomerId.Value = guaranteeList.CustomerId.Value.ToString();
            Customer customer = new CustomerService().GetById(guaranteeList.CustomerId.Value);
            if (customer != null)
            {
              txtCustomerName.Text = customer.Name;
              btneCustomerNo.Text = customer.CustomerNo;
            }
          }
          #endregion
        }
      }

      #region PurchaseDetail
      DataSet ds = new GuaranteeService().SearchByGuanranteeListId(guaranteeId);
      if (ds != null && ds.Tables.Count > 0)
      {
        GuaranteeDetailTable = ds.Tables[0];
        GuaranteeDetailTable.PrimaryKey = new DataColumn[] { GuaranteeDetailTable.Columns["Id"] };
        GuaranteeDetailTable.Columns.Add("Deleted", typeof(bool));
      }
      gvGuaranteeDetail.DataSource = GuaranteeDetailTable;
      gvGuaranteeDetail.DataBind();
      #endregion
    }

    private void LoadCustomerList()
    {
      string customerCode = null;
      string customerName = null;
      string phone = null;
      if (!string.IsNullOrEmpty(txtSearchCode.Text.Trim()))
      {
        customerCode = txtSearchCode.Text.Trim();
      }

      if (!string.IsNullOrEmpty(txtSearchName.Text.Trim()))
      {
        customerName = txtSearchName.Text.Trim();
      }

      if (!string.IsNullOrEmpty(txtSearchPhone.Text.Trim()))
      {
        phone = txtSearchPhone.Text.Trim();
      }

      TList<Customer> ds = new CustomerService().Search(customerCode, customerName, phone);
      gvCustomer.DataSource = ds;
      gvCustomer.DataBind();

    }

    private string SaveDetail()
    {
      GuaranteeService service = new GuaranteeService();

      #region Check parameters
      if (!string.IsNullOrEmpty(hfDetailCode.Value))
      {
        string[] codeList = hfDetailCode.Value.Split(',');
        foreach (string code in codeList)
        {
          DataSet ds = new PreviousPurchaseService().GetByCode(code.ToUpper());
          if (ds == null || ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)
          {
            return "Mã sản phẩm '" + code + "' chưa được bán, yêu cầu chọn mã khác.";
          }

          DataSet dsGuarantee= new GuaranteeService().GetByCode(code.ToUpper());
          if (dsGuarantee != null && dsGuarantee.Tables.Count > 0)
          {
            foreach (DataRow row in dsGuarantee.Tables[0].Rows)
            {
              if (row["ReturnDate"] == null || row["ReturnDate"] == DBNull.Value)
              {
                return "Mã sản phẩm '" + code + "' đang được bảo hành, yêu cầu chọn mã khác.";
              }
            }
          }
        }
      }

     

      #endregion

      #region Save to temp table
      try
      {
        int detailId;
        if (!string.IsNullOrEmpty(hfDetailCode.Value))
        {
          string[] codeList = hfDetailCode.Value.Split(',');
          foreach (string code in codeList)
          {
            DataRow row = null;
            if (int.TryParse(hfDetailId.Value, out detailId))
            {
              row = GuaranteeDetailTable.Rows.Find(detailId);
            }

            if (row == null)
            {
              row = GuaranteeDetailTable.NewRow();
              row["Id"] = DetailId;
              DetailId -= 1;
              GuaranteeDetailTable.Rows.Add(row);
            }

            row["Code"] = code.ToUpper();
            row["ReceiveDate"] = deReceiveDate.Date;
            row["AttendReturn"] = deAttendReturn.Date;
            row["RepositoryId"] = Convert.ToInt32(cbxRepository.Value);
            row["RepositoryName"] = cbxRepository.Text;
            row["Deleted"] = false;
          }
        }
        return "SaveDetail";
      }
      catch (Exception ex)
      {
        WriteLog("PurchaseInfo::SavePurchaseDetail", ex);
        return "Có lỗi trong quá trình lưu dữ liệu";
      }
      #endregion
    }

    private void LoadDetailList()
    {
      gvGuaranteeDetail.DataSource = GuaranteeDetailTable;
      gvGuaranteeDetail.FilterExpression = "Deleted <> true";
      gvGuaranteeDetail.DataBind();
    }

    private string Save()
    {
      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          #region Save Guarantee List
          Domains.GuaranteeList guaranteeList = null;
          if (!string.IsNullOrEmpty(hfGuaranteeId.Value))
          {
            int guaranteeListId = -1;
            int.TryParse(hfGuaranteeId.Value, out guaranteeListId);
            guaranteeList = new GuaranteeListService().GetById(guaranteeListId);
            if (guaranteeList == null) return "Không tìm thấy hóa đơn bảo hành tương ứng";
            guaranteeList.UpdatedBy = CurrentUser.Username;
            guaranteeList.UpdatedDate = DateTime.Now;
          }
          else
          {
            guaranteeList = new Domains.GuaranteeList();
            guaranteeList.CreatedBy = CurrentUser.Username;
            guaranteeList.CreatedDate = DateTime.Now;
            guaranteeList.TotalFee = 0;
          }
          guaranteeList.AttendReturn = deAttendReturn.Date;
          guaranteeList.ReceivedDate = deReceiveDate.Date;
          int customerId = 0;
          int.TryParse(hfCustomerId.Value, out customerId);
          guaranteeList.CustomerId = customerId;

          new GuaranteeListService().Save(guaranteeList);
          #endregion

          #region Guarantee Info
          GuaranteeService detailService = new GuaranteeService();
          foreach (DataRow row in GuaranteeDetailTable.Rows)
          {
            int detailId = Convert.ToInt32(row["Id"]);
            bool deleted = row["Deleted"] == DBNull.Value ? false : Convert.ToBoolean(row["Deleted"]);
            Guarantee detail = null;
            if (detailId > 0)
            {
              detail = detailService.GetById(detailId);
            }

            if (deleted)
            {
              #region Delete
              if (detail != null)
              {
                detailService.Delete(detail);
              }
              #endregion
            }
            else
            {
              #region Save
              if (detail == null)
              {
                detail = new Guarantee();
                detail.CreatedBy = CurrentUser.Username;
                detail.UpdatedDate = DateTime.Now;
                detail.ChargeFee = 0;
              }

              detail.Code = row["Code"] == DBNull.Value ? null : row["Code"].ToString().ToUpper();
              detail.GuanranteeListId = guaranteeList.Id;
              detail.RepositoryId = Convert.ToInt32(row["RepositoryId"]);
              detail.ReceiveDate = Convert.ToDateTime(row["ReceiveDate"]);
              detail.AttendReturn = Convert.ToDateTime(row["AttendReturn"]);
              detail.UpdatedBy = CurrentUser.Username;
              detail.UpdatedDate = DateTime.Now;
              detailService.Save(detail);
              row["Id"] = detail.Id;
              #endregion
            }
          }
          #endregion

          ConnectionScope.Complete();
        }
        return "Save";
      }
      catch (Exception ex)
      {
        WriteLog("GuaranteeDetail.aspx::Save", ex);
        return "Có lỗi trong quá trình lưu dữ liệu";
      }
    }

    private string DeleteGuaranteeDetail(int id)
    {
      try
      {
        DataRow row = GuaranteeDetailTable.Rows.Find(id);
        if (row != null)
        {
          row["Deleted"] = true;
        }

        return "DeleteDetail";
      }
      catch (Exception ex)
      {
        WriteLog("GuranteeDetail::DeletePurchaseDetai", ex);
        return "Có lỗi trong quá trình xóa dữ liệu";
      }
    }

    private string SavePreviousPurchase()
    {
      try
      {
        if(string.IsNullOrEmpty(hfCustomerId.Value.Trim()))
        {
          return "Phải chọn khách hàng";
        }
        if (dePurchaseDate.Date == DateTime.MinValue || dePurchaseDate.Date == null)
        {
          return "Phải nhập vào ngày mua hàng";
        }

        if (cbxProduct.Value == null)
        {
          return "Phải chọn sản phẩm";
        }
       
        //string code = txtPreviousCode.Text.Trim();
        if (string.IsNullOrEmpty(hfPreviousCode.Value.Trim()))
        {
          return "Phải nhập mã sản phẩm";
        }
        string[] codes = hfPreviousCode.Value.Split(',');
        foreach (string code in codes)
        {
          DataSet ds = new PreviousPurchaseService().GetByCode(code.ToUpper());
          if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
          {
            return "Mã sản phẩm đã tồn tại";
          }
          PreviousPurchase previousPurchase = new PreviousPurchase();
          previousPurchase.Code = code.ToUpper();
          previousPurchase.ProductId = Convert.ToInt32(cbxProduct.Value);
          previousPurchase.PurchaseDate = dePurchaseDate.Date;
          previousPurchase.Note = Utilities.SafeString(txtNote.Text);
          previousPurchase.CreatedBy = CurrentUser.Username;
          previousPurchase.CreatedDate = DateTime.Now;
          previousPurchase.CustomerId = Convert.ToInt32(hfCustomerId.Value);

          new PreviousPurchaseService().Save(previousPurchase);
        }
      }
      catch (Exception ex)
      {
        WriteLog("Save Previous Purchase", ex);
        return "Có lỗi trong quá trình lưu dữ liệu";
      }

      return "Previous";
    }

    #endregion

  }
}
